﻿using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApp1.Report
{
    /// <summary>
    /// WindowReport.xaml 的交互逻辑
    /// </summary>
    public partial class WindowReport : Window
    {
        public WindowReport()
        {
            InitializeComponent();
        }

       

        private string report_wenjianming { get; set; }

        private List<Orders> orders { get; set; }

        private List<Orders2> orders2 { get; set; }

        private string dt_set { get; set; }

        private List<ReportParameter> pr { get; set; }

        private string printerName { get; set; }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (orders.Count > 0)
            {
                show(orders, dt_set, pr);
            }
            else
            {
                show(orders2, dt_set, pr);
            }

        }


        public void init(string title, string report_wenjianming1, List<Orders> orders1, string dt_set1, List<ReportParameter> pr1,string printerName1)
        {
            this.Title = title;
            report_wenjianming = report_wenjianming1;
            orders = orders1;
            dt_set = dt_set1;
            pr = pr1;
            printerName = printerName1;

        }

        public void init(string title, string report_wenjianming1, List<Orders2> orders1, string dt_set1, List<ReportParameter> pr1, string printerName1)
        {
            this.Title = title;
            report_wenjianming = report_wenjianming1;
            orders2 = orders1;
            dt_set = dt_set1;
            pr = pr1;
            printerName = printerName1;

        }



        private void show(List<Orders> orders, string dataset, List<ReportParameter> pr)
        {


           
            reportViewer.LocalReport.DataSources.Clear();

            string path = Environment.CurrentDirectory;

            reportViewer.LocalReport.ReportPath = path + @"\Report\" + report_wenjianming;

            reportViewer.LocalReport.DataSources.Add(new ReportDataSource(dataset, orders));

            if (pr != null)
            {
                for (int i = 0; i < pr.Count; i++)
                {
                    try
                    {
                        reportViewer.LocalReport.SetParameters(pr[i]);
                    }
                    catch(Exception ex)
                    {
                        Console.WriteLine("error:"+ex.Message);
                    }
                }
            }
            
            reportViewer.RefreshReport();

            reportViewer.ZoomMode = ZoomMode.Percent;
            reportViewer.ZoomPercent = 100;

            
            if (string.IsNullOrEmpty(printerName))
            {
                this.DialogResult = true;
                return;
            }
            PrinterSys printer = new PrinterSys(printerName);
            string st=printer.getStatus().ToString();
            MessageBox.Show(st);
            
            Export(reportViewer.LocalReport);

            m_currentPageIndex = 0;

           // Print(printerName);




        }


        private void show(List<Orders2> orders, string dataset, List<ReportParameter> pr)
        {



            reportViewer.LocalReport.DataSources.Clear();

            string path = Environment.CurrentDirectory;

            reportViewer.LocalReport.ReportPath = path + @"\Report\" + report_wenjianming;

            reportViewer.LocalReport.DataSources.Add(new ReportDataSource(dataset, orders));

            if (pr != null)
            {
                for (int i = 0; i < pr.Count; i++)
                {
                    try
                    {
                        reportViewer.LocalReport.SetParameters(pr[i]);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("error:" + ex.Message);
                    }
                }
            }

            reportViewer.RefreshReport();

            reportViewer.ZoomMode = ZoomMode.Percent;
            reportViewer.ZoomPercent = 100;


            if (string.IsNullOrEmpty(printerName))
            {
                this.DialogResult = true;
                return;
            }
            PrinterSys printer = new PrinterSys(printerName);
            string st = printer.getStatus().ToString();
            //MessageBox.Show(st);

            Export(reportViewer.LocalReport);

            m_currentPageIndex = 0;

            Print(printerName);




        }


        private int m_currentPageIndex;

        private IList<Stream> m_streams;


        private Stream CreateStream(string name, string fileNameExtension,
        Encoding encoding, string mimeType, bool willSeek)

        {

            Stream stream = new FileStream(name + "." + fileNameExtension,

              FileMode.Create);

            m_streams.Add(stream);

            return stream;

        }



        private void Export(LocalReport report)

        {

            string deviceInfo =

              "<DeviceInfo>" +

             // "  <OutputFormat>PDF</OutputFormat>" +
              "  <OutputFormat>EMF</OutputFormat>" +

             // "  <PageWidth>6cm</PageWidth>" +
             // 
             // "  <PageHeight>15cm</PageHeight>" +
             // 
             // "  <MarginTop>0cm</MarginTop>" +
             // 
             // "  <MarginLeft>0cm</MarginLeft>" +
             // 
             // "  <MarginRight>0cm</MarginRight>" +
             // 
             // "  <MarginBottom>0cm</MarginBottom>" +

              "</DeviceInfo>";

            Warning[] warnings;

            m_streams = new List<Stream>();

            try

            {

                report.Render("Image", deviceInfo, CreateStream, out warnings);

            }

            catch (Exception ex)

            {

                Exception innerEx = ex.InnerException;//取内异常。因为内异常的信息才有用，才能排除问题。

                while (innerEx != null)

                {

                    MessageBox.Show(innerEx.Message);

                    innerEx = innerEx.InnerException;

                }

            }





            foreach (Stream stream in m_streams)

                stream.Position = 0;

        }



        private void PrintPage(object sender, PrintPageEventArgs ev)

        {

            Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);

            ev.Graphics.DrawImage(pageImage, 0, 0);



            m_currentPageIndex++;

            ev.HasMorePages = (m_currentPageIndex < m_streams.Count);

        }



        private void Print(string printerName)

        {

           

            if (m_streams == null || m_streams.Count == 0)

                return;



            PrintDocument printDoc = new PrintDocument();

            printDoc.PrinterSettings.PrinterName = printerName;

            if (!printDoc.PrinterSettings.IsValid)

            {

                string msg = String.Format("Can't find printer "+ printerName);

                Console.WriteLine(msg);

                return;

            }

            printDoc.PrintPage += new PrintPageEventHandler(PrintPage);

            printDoc.Print();

        }


        /// <summary>
        /// 获取打印机状态
        /// </summary>
        /// <param name="printerName">打印机名称</param>
        /// <param name="status">输出打印机状态</param>
        private static void GetPrinterStatus2(string printerName, ref uint status)
        {
            try
            {

                string lcPrinterName = printerName;
                IntPtr liHandle = IntPtr.Zero;
                if (!Win32.OpenPrinter(lcPrinterName, out liHandle, IntPtr.Zero))
                {
                    Console.WriteLine("print  is close");
                    return;
                }
                UInt32 level = 2;
                UInt32 sizeNeeded = 0;
                IntPtr buffer = IntPtr.Zero;
                Win32.GetPrinter(liHandle, level, buffer, 0, out sizeNeeded);
                buffer = Marshal.AllocHGlobal((int)sizeNeeded);
                if (!Win32.GetPrinter(liHandle, level, buffer, sizeNeeded, out sizeNeeded))
                {
                    Console.WriteLine(Environment.NewLine + "Fail GetPrinter:" + Marshal.GetLastWin32Error());
                    return;
                }

                Win32.PRINTER_INFO_2 info = (Win32.PRINTER_INFO_2)Marshal.PtrToStructure(buffer, typeof(Win32.PRINTER_INFO_2));
                status = info.Status;
                Marshal.FreeHGlobal(buffer);
                Win32.ClosePrinter(liHandle);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 对外接口,调去打印机信息
        /// </summary>
        /// <param name="printerName">打印机名称</param>
        /// <returns>返回打印机当前状态</returns>
        public static string GetPrinterStatus(string printerName)
        {
            uint intValue = 0;
            PrintDocument pd = new PrintDocument();
            printerName = printerName == "" ? pd.PrinterSettings.PrinterName : printerName;
            GetPrinterStatus2(printerName, ref intValue);
            string strRet = string.Empty;
            switch (intValue)
            {
                case 0:
                    strRet = "准备就绪（Ready）";
                    break;
                case 4194432:
                    strRet = "被打开（Lid Open）";
                    break;
                case 144:
                    strRet = "打印纸用完（Out of Paper）";
                    break;
                case 4194448:
                    strRet = "被打开并且打印纸用完（Out of Paper && Lid Open）";
                    break;
                case 1024:
                    strRet = "打印中（Printing）";
                    break;
                case 32768:
                    strRet = "初始化（Initializing）";
                    break;
                case 160:
                    strRet = "手工送纸(Manual Feed in Progress)";
                    break;
                case 4096:
                    strRet = "脱机(Offline)";
                    break;
                default:
                    strRet = "未知状态（unknown state）";
                    break;
            }
            return strRet;
        }
    }
    public class Win32
    {
        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool OpenPrinter(string printer, out IntPtr handle, IntPtr printerDefaults);
        [DllImport("winspool.drv")]
        public static extern bool ClosePrinter(IntPtr handle);
        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool GetPrinter(IntPtr handle, UInt32 level, IntPtr buffer, UInt32 size, out UInt32 sizeNeeded);
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct PRINTER_INFO_2
        {
            public string pServerName;
            public string pPrinterName;
            public string pShareName;
            public string pPortName;
            public string pDriverName;
            public string pComment;
            public string pLocation;
            public IntPtr pDevMode;
            public string pSepFile;
            public string pPrintProcessor;
            public string pDatatype;
            public string pParameters;
            public IntPtr pSecurityDescriptor;
            public UInt32 Attributes;
            public UInt32 Priority;
            public UInt32 DefaultPriority;
            public UInt32 StartTime;
            public UInt32 UntilTime;
            public UInt32 Status;
            public UInt32 cJobs;
            public UInt32 AveragePPM;
        }
    }





}







